package org.sam.swing.table;

import java.util.Map;
import java.util.Set;

import org.sam.swing.table.verification.VerificatEventListener;
import org.sam.swing.table.verification.Verification;

/**
 * 对tablemodel做扩展的方法集合
 * @author sam
 *
 * @param <T>
 */
public interface JTableModel<T> {
	
	/**
	 * 当前的数据检索方式，默认realtime
	 * @return
	 */
	RetrieveModel getRetrieveModel();
	
	/**
	 * 数据检索方式，默认realtime
	 * @param model
	 */
	void setRetrieveModel(RetrieveModel model);
	
	/**
	 * 原始的数据集合
	 * 
	 * @return
	 */
	T getOrginal();

	/**
	 * 原始的数据集合
	 * 
	 * @param orginal
	 */
	void setOrginal(T orginal);

	/**
	 * 已删除的数据集合
	 * 
	 * @return
	 */
	T getDeletes();

	/**
	 * 已删除的数据集合
	 * 
	 * @param deletes
	 */
	void setDeletes(T deletes);

	/**
	 * 新增数据的集合
	 * 
	 * @return
	 */
	T getCreates();

	/**
	 * 新增数据的集合
	 * 
	 * @param creates
	 */
	void setCreates(T creates);

	/**
	 * 更新的数据集合
	 * 
	 * @return
	 */
	T getModified();

	/**
	 * 更新的数据集合
	 * 
	 * @param modified
	 */
	void setModified(T modified);

	/**
	 * 清空所有缓冲区
	 */
	void resetUpdate();

	/**
	 * 初始化数据的操作
	 * 
	 * @return 0无数据 -1出错 成功返回行数
	 * @exception Exception
	 */
	int onRetrieve() throws Exception;

	/**
	 * 删除时候执行的操作
	 * 
	 * @return
	 * @exception Exception
	 */
	boolean onDelete(int moduleRow) throws Exception;

	/**
	 * 插入的时候执行的操作
	 * 
	 * @param moduleRow
	 * @return
	 * @exception Exception
	 */
	boolean onInsert(int moduleRow) throws Exception;

	/**
	 * 当执行追加的时候执行的操作
	 * 
	 * @return
	 * @exception Exception
	 */
	boolean onAppend() throws Exception;

	/**
	 * 获取列列表
	 * 
	 * @return
	 */
	JSTableColumn[] getTableColumns();

	/**
	 * 快速检索模式，默认不开启 主要是retrieve的时候，不切换数据库
	 * 
	 * @return
	 */
	boolean isQuickRetrieveModel();

	/**
	 * 快速检索模式，默认不开启 主要是retrieve的时候，不切换数据库
	 * 
	 * @param quickRetrieveModel
	 */
	void setQuickRetrieveModel(boolean quickRetrieveModel);

	/**
	 * 是否编辑状态
	 * 
	 * @return
	 */
	Boolean getEditable();

	/**
	 * 是否编辑状态
	 * 
	 * @param editable
	 */
	void setEditable(Boolean editable);

	/**
	 * 是否在retrieve的时候加入空白行
	 * 
	 * @return
	 */
	boolean isRetrieveWithEmptyRow();

	/**
	 * 是否在retrieve的时候加入空白行
	 * 
	 * @param retrieveWithEmptyRow
	 */
	void setRetrieveWithEmptyRow(boolean retrieveWithEmptyRow);

	/**
	 * 保护起来的单元格
	 * 
	 * @return
	 */
	Map<Integer, Set<Integer>> getProtectCell();

	/**
	 * 保护起来的单元格
	 * 
	 * @param protectCell
	 */
	void setProtectCell(Map<Integer, Set<Integer>> protectCell);

	/**
	 * 注入的tablemodel对象
	 * 
	 * @return
	 */
	JSTableModelLinster<T> getTableModelLinster();

	/**
	 * 注入的tablemodel对象
	 * 
	 * @param tableModelLinster
	 */
	void setTableModelLinster(JSTableModelLinster<T> tableModelLinster);

	/**
	 * 加入一个对象变化事件监听
	 * 
	 * @param l
	 */
	void addStateChangeListener(TableModelStateChangeListener l);

	/**
	 * 移除对象变化变化监听事件
	 * 
	 * @param l
	 */
	void removeStateChangeListener(TableModelStateChangeListener l);

	/**
	 * 重写的返回字段是否可编辑的功能
	 */
	boolean isCellEditable(int row, int column);

	/**
	 * 查询是否有需要更新的操作
	 * 
	 * @return
	 */
	boolean hasChange();

	/**
	 * 交换2行数据，无保存状态交互数据
	 * 
	 * @param srcRow
	 *            原始数据行
	 * @param tarRow
	 *            目标数据行
	 * @throws Exception
	 */
	void moveRow(int srcRow, int tarRow) throws Exception;

	/**
	 * 收集当前变更后的数据集合
	 * 
	 * @throws Exception
	 */
	T getDatas() throws Exception;

	/**
	 * 重建索引列
	 * 
	 * @param colIndex
	 *            列索引
	 * @param begin
	 *            开始值，比如1，0作为索引开始值
	 * @param seed
	 *            增速
	 * @throws Exception
	 */
	void reBuildIndex(int colIndex, int begin, int seed) throws Exception;

	/**
	 * 返回当前选中行的数据
	 * 
	 * @param modelRow
	 *            模式行
	 * @return 返回当前行的数据
	 * @throws Exception
	 */
	Object getData(int modelRow) throws Exception;

	/**
	 * 拿到一个一个单元格对应的数据
	 * 
	 * @param modelRow
	 *            模式行
	 * @return
	 * @throws Exception
	 */
	Object[] getCellData(int modelRow) throws Exception;

	/**
	 * 新生成一个数据,但不插入集合
	 * 
	 * @return 新生成一个数据集合
	 * @throws Exception
	 */
	Object[] createNew() throws Exception;

	/**
	 * 根据实体对象
	 * 
	 * @param data
	 *            查找数据所在的索引位置
	 * @return
	 * @throws Exception
	 */
	int findIndexOf(Object data) throws Exception;

	/**
	 * 清空所有当前显示数据 并且清空所有缓冲区
	 * 
	 * @throws Exception
	 */
	void clear() throws Exception;

	/**
	 * 使用泛型类型插入一行数据
	 * 
	 * @param row
	 *            要插入行的位置
	 * @param t
	 *            数据
	 * @throws Exception
	 */
	void insert(int row, Object t) throws Exception;

	/**
	 * 替换掉行的数据操作 但是不记录到系统里
	 * 
	 * @param row
	 *            行
	 * @param t
	 *            数据
	 * @throws Exception
	 */
	void replace(int row, Object t) throws Exception;

	/**
	 * 获取当前列的数据类型
	 */
	Class<?> getColumnClass(int columnIndex);

	/**
	 * 清空数据显示
	 * 
	 * @throws Exception
	 */
	void removeAll() throws Exception;

	/**
	 * 更新一个单元格数据，但是不记录到系统里
	 * 
	 * @param aValue
	 *            新值
	 * @param row
	 *            行号
	 * @param column
	 *            列
	 * @throws Exception
	 */
	void updateValueAt(Object aValue, int row, int column) throws Exception;

	/**
	 * 获取一列的数据
	 * 
	 * @param colIndex
	 *            列所在的model索引位置
	 * @param beginRow
	 *            开始行
	 * @param endRow
	 *            结束行
	 * @throws Exception
	 */
	Object[] getColData(int colIndex, int beginRow, int endRow) throws Exception;

	/**
	 * 更新操作
	 * 
	 * @return 更新操作
	 * @throws Exception
	 *             出错抛出异常
	 */
	boolean update() throws Exception;

	/**
	 * 加载数据的操作
	 * 
	 * @return 负数出错 其它为返回的加载数据行数
	 * @throws Exception
	 *             抛出一切之错误
	 */
	int retrieve() throws Exception;

	/**
	 * 删除操作
	 * 
	 * @return true 成功 false失败
	 * @param modelRow
	 *            要删除的table model数据行
	 * @throws Exception
	 *             抛出异常
	 */
	boolean delete(int modelRow) throws Exception;

	/**
	 * 插入一行数据的操作
	 * 
	 * @return true插入成功 false插入失败
	 * @throws Exception
	 *             抛出一切可以抛出之异常
	 */
	boolean append() throws Exception;

	/**
	 * 插入一行数据
	 * 
	 * @param index插入行的索引位置
	 * @return
	 * @throws Exception
	 */
	boolean insert(int modelRow) throws Exception;
	
	/**
	 * 是否使用客户端校验;
	 * 在ModelAdapter里客户端里由重写的地方校验;
	 * 这里仅做标识,不做处理
	 * @return
	 */
	boolean isUseClientVerification();
	
	/**
	 * 是否使用客户端校验;
	 * 在ModelAdapter里客户端里由重写的地方校验;
	 * 这里仅做标识,不做处理
	 * @param used
	 */
	void setUseClientVerification(boolean used);
	
	/**
	 * 获取校验器对象，非null表示开启校验
	 * @return
	 */
	Verification getVerification();
	
	/**
	 * 校验器对象，非null表示开启校验
	 * @param verification
	 */
	void setVerification(Verification verification);
	
	/**
	 * 是否开启列对象校验;(设置列上的vertifactor对象)
	 * 在ModelAdapter里客户端里由重写的地方校验;
	 * @return
	 */
	boolean isTableColumnVerificatior();
	
	/**
	 * 是否开启列对象校验;(设置列上的vertifactor对象)
	 * 在ModelAdapter里客户端里由重写的地方校验;
	 * @param verificat
	 */
	void setTableColumnVerificatior(boolean verificat);
	
	/**
	 * 添加一个校验事件对象
	 * @param listener
	 */
	void addVerificatEventListener(VerificatEventListener listener);
	
	/**
	 * 移除一个校验事件对象
	 * @param listener
	 */
	void removeVerificatEventListener(VerificatEventListener listener);
	
	/**
	 * 表格刷新模式枚举
	 * 目前只实现了实时和同步模式
	 * @author sam
	 *
	 */
	public enum RetrieveModel{
		
		/**
		 * 实时模式，线程不安全
		 */
		RealTime,
		
		/**
		 * 同步模式，尝试获取锁，未获取不刷新
		 */
		Synchronized,
		
		/**
		 * 异步刷新模式，未实现
		 */
		Async,
		
		/**
		 * 按需加载模式,未实现
		 */
		AsNeeded
	}

}